package com.ayou.parsing;

import cn.hutool.core.util.StrUtil;

/**
 * @description: sql参数解析器
 * 将sql: select * from t_user where id=#{id} 解析成 select * from t_user where id=?
 *
 * @author: ayouman
 * @date: 2024/6/28 18:01
 */
public class GenericTokenParser {
    private String openToken = "#{"; // 参数界限开始标志 #{
    private String closeToken = "}"; // 参数界限结束标志 }

    private TokenHandler tokenHandler;

    public GenericTokenParser(TokenHandler tokenHandler) {
        this.tokenHandler = tokenHandler;
    }

    public String parse(String sql) {
        if (StrUtil.isBlank(sql) ) {
            return sql;
        }

        // TODO: 异常情况的处理
        // TODO: 不能替换固定参数中的#{}
        // 1. #{} 空参数
        // 2. #{  只有开始token
        // 3. } 只有结束token
        // 4. }#{ 位置颠倒
        // O(n)复杂度 只需要遍历一次
        char[] charArray = sql.toCharArray();
        StringBuilder res = new StringBuilder();
        int offset = 0;
        int oLen = openToken.length();
        int cLen = closeToken.length();
        while (offset < sql.length()) {
            // 找到openToken的位置
            int start = sql.indexOf(openToken, offset);
            if (start == -1) {
                res.append(charArray, offset, sql.length() - offset);
                break;
            }
            // 添加在这之前的
            res.append(charArray, offset, start - offset);
            // 找到closeToken的位置
            int end = sql.indexOf(closeToken, start);
            if (end == -1) {
                res.append(charArray, start, sql.length() - start);
                break;
            }
            // 提取参数名 暂时先打印
            String paramName = new String(charArray, start + oLen, end - (start + oLen));
            if (StrUtil.isBlank(paramName)) {
                System.out.println("异常： 空参数");
            }
            // 添加 ?
            res.append(tokenHandler.handleToken(paramName));
            // 更新offset位置
            offset = end + cLen;
        }

        return res.toString();
    }
}
